package org.kzwl.book.controller.filter;

import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import lombok.extern.slf4j.Slf4j;
import org.kzwl.book.controller.annotation.PassToken;
import org.kzwl.book.controller.annotation.UserLoginToken;
import org.kzwl.comm.advice.BizException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @ClassName JWTFilter
 * @Description
 * @Author JiaHeng.Guo
 * @Date 2019/7/24 10:01
 */
@Slf4j
public class JWTHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception
    {
//        if (!"".equals(httpServletRequest.getHeader(""))
//        {
//            httpServletRequest.getSession().getId();
//        }

//        httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));//支持跨域请求
//        httpServletResponse.setHeader("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type, Accept,Access-Token");
//        httpServletResponse.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS,PATCH");
//        httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");//是否支持cookie跨域

        log.info("请求头:[{}]",httpServletRequest);

        log.info("请求地址:{}",httpServletRequest.getRequestURI());
        //TODO:暂时这样处理
        if(httpServletRequest.getRequestURI().equals("/upload/oneFile"))
        {
            return true;
        }
        // 从 http 请求头中取出 token
        String token = httpServletRequest.getHeader("token");
        //   如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        //拿到请求的方法所加的注释
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释，有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //检查有没有需要用户权限的注解
        //todo: 此处不做验证是否需要用户注解。意为所有请求都需要验证
//        if (method.isAnnotationPresent(UserLoginToken.class)) {
        UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
//            if (userLoginToken.required()) {
        // 执行认证
        if (token == null) {
            throw new BizException("456");                                                                                                           
        }
        // 获取 token 中的 user id
        String user;
        try {
            //拿到了用户的信息
            user = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            throw new BizException("401");
        }
        //判断用户是否存在
//                TSysUser user = userService.selectById(userId);
//                if (user == null) {
//                    throw new RuntimeException("用户不存在，请重新登录");
//                }
//                // 验证 token
//                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
//                try {
//                    jwtVerifier.verify(token);
//                } catch (JWTVerificationException e) {
//                    throw new RuntimeException("401");
//                }
//                return true;
//            }
//        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {
    }
}
